<template>
  <div class="header-container">
    <van-search v-model="qtext" placeholder="请输入搜索关键词" shape="round" @search="onSearch">
      <template #left>
        <span class="app-name">轻商城</span>
      </template>
    </van-search>
  </div>
  <div class="main-container">
    <div class="van-list-container">
      <van-list v-model:loading="listLoading" :finished="listFinished" :immediate-check="false" finished-text="没有更多了"
        @load="onListLoad">
        <div class="swipe-container">
          <van-swipe style="height: 100%" :autoplay="3000" indicator-color="white">
            <template v-for="carousel of carousels" :key="carousel.id">
              <van-swipe-item>
                <van-image :src="carousel.imgUrl" style="height: 150px; width: 100%;" @click="clickCarousel(carousel)">
                </van-image>
              </van-swipe-item>
            </template>
          </van-swipe>
        </div>
        <div class="vajra-container">
          <van-grid style="height: 100%" :gutter="5" :border="false">
            <van-grid-item icon="sign" text="签到" icon-color="#41d882" @click="noImplemention()" />
            <van-grid-item icon="clock-o" text="限时抢购" icon-color="#f85669" @click="noImplemention()" />
            <van-grid-item icon="coupon-o" text="领券" icon-color="#434bf8" @click="noImplemention()" />
            <van-grid-item icon="gift-o" text="积分商城" icon-color="#fd862a" @click="noImplemention()" />
          </van-grid>
        </div>
        <div class="product-container">
          <header class="product-header">最新推荐</header>
          <div class="product-list">
            <template v-for="item of newProducts" :key="item.id">
              <div class="product-item" @click="showProductDetail(item)">
                <img :src="item.imgUrl" alt="" />
                <div class="product-info">
                  <div class="product-title">
                    <van-tag round type="danger">自营</van-tag>
                    {{ item.name }}
                  </div>
                  <div class="product-footer">
                    <div class="product-price">¥ {{ item.price }}</div>
                    <div class="product-action">
                      <van-icon name="shopping-cart-o" @click="addCartItem(item, $event)" />
                    </div>
                  </div>
                </div>
              </div>
            </template>
          </div>

          <header class="product-header">热销商品</header>
          <div class="product-list">
            <template v-for="item of hotProducts" :key="item.id">
              <div class="product-item" @click="showProductDetail(item)">
                <img :src="item.imgUrl" alt="" />
                <div class="product-info">
                  <div class="product-title">
                    <van-tag round type="danger">自营</van-tag>
                    {{ item.name }}
                  </div>
                  <div class="product-footer">
                    <div class="product-price">¥ {{ item.price }}</div>
                    <div class="product-action">
                      <van-icon name="shopping-cart-o" @click="addCartItem(item, $event)" />
                    </div>
                  </div>
                </div>
              </div>
            </template>
          </div>
          <template v-if="products && products.length > 0">
            <header class="product-header">为你推荐</header>
            <div class="product-list">
              <template v-for="item of products" :key="item.id">
                <div class="product-item" @click="showProductDetail(item)">
                  <img :src="item.imgUrl" alt="" />
                  <div class="product-info">
                    <div class="product-title">
                      <van-tag round type="danger">自营</van-tag>
                      {{ item.name }}
                    </div>
                    <div class="product-footer">
                      <div class="product-price">¥ {{ item.price }}</div>
                      <div class="product-action">
                        <van-icon name="shopping-cart-o" @click="addCartItem(item, $event)" />
                      </div>
                    </div>
                  </div>
                </div>
              </template>
            </div>
          </template>
          <van-empty v-else />
        </div>
      </van-list>
    </div>
  </div>
  <div class="footer-container">
    <tab-bar />
  </div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs } from "vue";
import TabBar from "@/components/TabBar.vue";
import productService from "@/services/product.service";
import PmsProduct from "@/entity/PmsProduct";
import { AxiosError } from "axios";
import { Toast } from "vant";
import { useRouter } from "vue-router";
import Page from "@/entity/Page";
import OmsCartItemCreationParam from "@/entity/OmsCartItemCreationParam";
import cartItemService from "@/services/cart-item.service";
import SmsCarousel from "@/entity/SmsCarousel";
import SmsLinkType from "@/entity/SmsLinkType";
import homeService from "@/services/home.service";

type StateType = {
  listLoading: boolean;
  listFinished: boolean;
  newProducts: PmsProduct[];
  hotProducts: PmsProduct[];
  products: PmsProduct[];
  pageProduct?: Page<PmsProduct> | null;
  carousels: SmsCarousel[];
  qtext: string;
};

export default defineComponent({
  components: {
    TabBar,
  },
  setup() {
    const router = useRouter();
    const state = reactive<StateType>({
      listLoading: false,
      listFinished: false,
      newProducts: [],
      hotProducts: [],
      products: [],
      pageProduct: null,
      carousels: [],
      qtext: "",
    });

    onMounted(() => {
      load();
    });

    const load = async () => {
      await loadHomeData();
      await loadProducts();
    };

    const loadHomeData = async () => {
      try {
        const homeData = await homeService.getData();
        state.carousels = homeData.carousels;
        state.newProducts = homeData.newProducts;
        state.hotProducts = homeData.hotProducts;
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
      }
    };

    const loadProducts = async (no?: number, size?: number) => {
      try {
        state.listLoading = true;
        const pageProduct =
          no == null
            ? await productService.page()
            : await productService.page(no, size);
        state.pageProduct = pageProduct;
        state.products = [...state.products, ...pageProduct.content];
        state.listFinished = state.pageProduct.last;
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
        state.listLoading = false;
      }
    };

    const onListLoad = () => {
      loadProducts(
        state.pageProduct ? state.pageProduct.number + 1 : undefined,
        state.pageProduct ? state.pageProduct.size : undefined
      );
    };

    const showProductDetail = (p: PmsProduct) => {
      router.push({
        path: "/product-detail",
        query: {
          id: p.id,
        },
      });
    };

    const addCartItem = async (p: PmsProduct, evt: MouseEvent) => {
      evt.stopPropagation();
      evt.stopImmediatePropagation();
      try {
        const param: OmsCartItemCreationParam = {
          productId: p.id,
          quantity: 1,
        };
        await cartItemService.createOrUpdate(param);
      } catch (e) {
        if (e instanceof AxiosError && e.response?.status == 401) {
          Toast.fail("请先登录");
          router.push("/login");
          return;
        }
        Toast.fail("加载失败");
        throw e;
      } finally {
      }
    };

    const clickCarousel = (carousel: SmsCarousel) => {
      if (carousel.linkType == SmsLinkType.LINK) {
        if (carousel.linkUrl) {
          window.location.href = carousel.linkUrl;
        }
      } else if (carousel.linkType == SmsLinkType.PRODUCT) {
        if (carousel.productId != null) {
          const p = new PmsProduct();
          p.id = carousel.productId;
          showProductDetail(p);
        }
      }
    };

    const noImplemention = () => {
      Toast("敬请期待");
    }

    const onSearch = (val: string) => {
      router.push({
        path: "/product",
        query: {
          qtext: val
        },
      });
    };

    return {
      ...toRefs(state),
      onListLoad,
      showProductDetail,
      addCartItem,
      clickCarousel,
      noImplemention,
      onSearch,
    };
  },
});
</script>

<style scoped>
.header-container {
  position: fixed;
  top: 0;
  height: 54px;
  left: 0;
  width: 100%;
}

.main-container {
  position: fixed;
  top: 54px;
  bottom: var(--van-tabbar-height);
  left: 0;
  width: 100%;
}

.footer-container {}

.app-name {
  padding: 0 10px;
  color: var(--van-danger-color);
  font-size: 20px;
  font-weight: bold;
}

.van-list-container {
  height: 100%;
  overflow-y: scroll;
}

.swipe-container {
  height: 150px;
}

.vajra-container {
  height: 80px;
  padding: 5px;
}

.product-container {}

.product-header {
  background: #f9f9f9;
  height: 50px;
  line-height: 50px;
  text-align: center;
  color: var(--van-danger-color);
  font-size: 16px;
  font-weight: 500;
}

.product-list {
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
}

.product-item {
  box-sizing: border-box;
  width: 50%;
  border-bottom: 1px solid #e9e9e9;
  padding: 10px 10px;
}

.product-item img {
  display: block;
  width: 120px;
  height: 120px;
  margin: 0 auto;
}

.product-info {
  font-size: 14px;
  padding: 10px 0;
}

.product-title {
  color: #222333;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.product-footer {
  justify-content: space-between;
  display: flex;
  flex-direction: row;
}

.product-price {
  color: var(--van-danger-color);
}

.product-action {}

.product-item:nth-child(2n + 1) {
  border-right: 1px solid #e9e9e9;
}
</style>
